package com.tdcy.framework.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

import com.tdcy.framework.exception.BaseException;

public class DateUtils {

	/**
	 * 空安全的日期时间格式化
	 * 
	 * @param date
	 *            需要格式化的日期
	 * @param pattern
	 *            日期时间的格式化表达示
	 * @return 格式化后输出的字符串
	 */
	public static String format(Date date, String pattern) {
		return date != null ? new SimpleDateFormat(pattern).format(date) : "";
	}

	/**
	 * 空安全的日期时间格式化
	 * 
	 * @param calendar
	 *            需要格式化的日期
	 * @param pattern
	 *            日期时间的格式化表达示
	 * @return 格式化后输出的字符串
	 */
	public static String format(Calendar calendar, String pattern) {
		return calendar != null ? format(calendar.getTime(), pattern) : "";
	}

	/**
	 * 空安全的日期时间格式化yyyy/MM/dd HH:mm:ss.SSS
	 * 
	 * @param date
	 *            需要格式化的日期
	 * @return 格式化后输出的字符串
	 */
	public static String formatStandard(Date date) {
		return format(date, "yyyy/MM/dd HH:mm:ss.SSS");
	}

	/**
	 * 空安全的日期时间格式化yyyy/MM/dd
	 * 
	 * @param date
	 *            需要格式化的日期
	 * @return 格式化后输出的字符串
	 */
	public static String formatStandardDay(Date date) {
		return format(date, "yyyy/MM/dd");
	}

	/**
	 * 空安全的日期时间格式化yyyyMMddHHmmss
	 * 
	 * @param date
	 *            需要格式化的日期
	 * @return 格式化后输出的字符串
	 */
	public static String formatBriefSec(Date date) {
		return format(date, "yyyyMMddHHmmss");
	}

	/**
	 * 空安全的日期时间格式化yyyyMMdd
	 * 
	 * @param date
	 *            需要格式化的日期
	 * @return 格式化后输出的字符串
	 */
	public static String formatBriefDay(Date date) {
		return format(date, "yyyyMMdd");
	}

	/**
	 * <p>
	 * 按指定的格式，将字符串解析成日期
	 * </p>
	 * <b>最后修改时间：</b><br>
	 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2012-10-24上午10:20:34
	 * 
	 * @param dateStr
	 *            需要解析的字符串
	 * @param pattern
	 *            按什么格式解析
	 * @return 日期
	 */
	public static Date parse(String dateStr, String pattern) {
		try {
			return new SimpleDateFormat(pattern).parse(dateStr);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 字符串解析成日期，字符串格式yyyyMMddHHmmss
	 * 
	 * @param dateStr
	 *            需要解析的字符串
	 * @return 日期
	 */
	public static Date parseBriefSec(String dateStr) {
		return parse(dateStr, "yyyyMMddHHmmss");
	}

	/**
	 * 字符串解析成日期，字符串格式yyyyMMdd
	 * 
	 * @param dateStr
	 *            需要解析的字符串
	 * @return 日期
	 */
	public static Date parseBriefDay(String dateStr) {
		return parse(dateStr, "yyyyMMdd");
	}

	/** */
	/**
	 * 取得某天相加(减)後的那一天
	 * 
	 * @param date
	 * @param num
	 *            (可正可负)
	 * @return
	 */
	public static Date getAnotherDate(Date date, int num) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_YEAR, num);
		return c.getTime();
	}

	/** */
	/**
	 * 取得某月的的最后一天
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static Date getLastDayOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);// 年
		cal.set(Calendar.MONTH, month - 1);// 月，因为Calendar里的月是从0开始，所以要减1
		cal.set(Calendar.DATE, 1);// 日，设为一号
		cal.add(Calendar.MONTH, 1);// 月份加一，得到下个月的一号
		cal.add(Calendar.DATE, -1);// 下一个月减一为本月最后一天
		return cal.getTime();// 获得月末是几号
	}

	/** */
	/**
	 * 取得某月的的最后一天
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static Date getLastDayOfMonthByDay(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DATE, 1);// 日，设为一号
		c.add(Calendar.MONTH, 1);// 月份加一，得到下个月的一号
		c.add(Calendar.DATE, -1);// 下一个月减一为本月最后一天
		return c.getTime();
	}

	/** */
	/**
	 * 取得某天是一年中的多少周
	 * 
	 * @param date
	 * @return
	 */
	public static int getWeekOfYear(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setMinimalDaysInFirstWeek(7);
		c.setTime(date);
		return c.get(Calendar.WEEK_OF_YEAR);
	}

	/** */
	/**
	 * 取得某天所在周的第一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
		return c.getTime();
	}

	/** */
	/**
	 * 取得某天所在周的最后一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
		return c.getTime();
	}

	/** */
	/**
	 * 取得某一年共有多少周
	 * 
	 * @param year
	 * @return
	 */
	public static int getMaxWeekNumOfYear(int year) {
		Calendar c = new GregorianCalendar();
		c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
		return getWeekOfYear(c.getTime());
	}

	/** */
	/**
	 * 取得某年某周的第一天 对于交叉:2008-12-29到2009-01-04属于2008年的最后一周,2009-01-05为2009年第一周的第一天
	 * 
	 * @param year
	 * @param week
	 * @return
	 */
	public static Date getFirstDayOfWeek(int year, int week) {
		Calendar calFirst = Calendar.getInstance();
		calFirst.set(year, 0, 7);
		Date firstDate = getFirstDayOfWeek(calFirst.getTime());

		Calendar firstDateCal = Calendar.getInstance();
		firstDateCal.setTime(firstDate);

		Calendar c = new GregorianCalendar();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DATE, firstDateCal.get(Calendar.DATE));

		Calendar cal = (GregorianCalendar) c.clone();
		cal.add(Calendar.DATE, (week - 1) * 7);
		firstDate = getFirstDayOfWeek(cal.getTime());

		return firstDate;
	}

	/** */
	/**
	 * 取得某年某周的最后一天 对于交叉:2008-12-29到2009-01-04属于2008年的最后一周, 2009-01-04为
	 * 2008年最后一周的最后一天
	 * 
	 * @param year
	 * @param week
	 * @return
	 */
	public static Date getLastDayOfWeek(int year, int week) {
		Calendar calLast = Calendar.getInstance();
		calLast.set(year, 0, 7);
		Date firstDate = getLastDayOfWeek(calLast.getTime());

		Calendar firstDateCal = Calendar.getInstance();
		firstDateCal.setTime(firstDate);

		Calendar c = new GregorianCalendar();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DATE, firstDateCal.get(Calendar.DATE));

		Calendar cal = (GregorianCalendar) c.clone();
		cal.add(Calendar.DATE, (week - 1) * 7);
		Date lastDate = getLastDayOfWeek(cal.getTime());

		return lastDate;
	}

	/**
	 * 获得日期所在月的最后一天
	 * 
	 * @param date
	 * @return
	 */
	public static int getLastDayOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int end = c.getActualMaximum(Calendar.DAY_OF_MONTH);
		return end;
	}

	/**
	 * 获得日期所在月的第一天
	 * 
	 * @param date
	 * @return
	 */
	public static int getFirstDayOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int begin = c.getActualMinimum(Calendar.DAY_OF_MONTH);
		return begin;
	}

	/** 缺省日期格式（java). */
	public static final java.lang.String DATE_FORMAT = "yyyy-MM-dd";

	/** 缺省日期时间格式(java). */
	public static final java.lang.String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	/** 缺省时间格式(java). */
	public static final java.lang.String TIME_FORMAT = "HH:mm:ss";

	/** 缺省日期格式（sql). */
	public static final java.lang.String SQLDATE_FORMAT = "yyyy-mm-dd";

	/** 缺省日期时间格式(sql). */
	public static final java.lang.String TIMESTAMP_FORMAT = "yyyy-mm-dd hh24:mi:ss";

	/** 缺省时间格式(sql). */
	public static final java.lang.String SQLTIME_FORMAT = "hh24:mi:ss";

	/**
	 * 判断字符串是否是日期格式.
	 * 
	 * @param strDate
	 *            具有日期格式的字符串(yyyy-MM-dd)
	 * 
	 * @return boolean 是否是日期格式
	 */
	public static boolean isDate(String strDate) {
		try {
			SimpleDateFormat sdfDate = new SimpleDateFormat(DATE_FORMAT);
			sdfDate.parse(strDate);
			return true;
		} catch (ParseException pe) {
			return false;
		}
	}

	/**
	 * 判断字符串是否是符合指定的日期格式.
	 * 
	 * @param strDate
	 *            具有日期格式的字符串
	 * @param strFormat
	 *            格式 yyyy-MM-dd HH:mm:ss
	 * 
	 * @return boolean 是否是日期格式
	 */
	public static boolean isDate(String strDate, String strFormat) {
		try {
			SimpleDateFormat df = new SimpleDateFormat(strFormat);
			df.parse(strDate);
			return true;
		} catch (ParseException pe) {
			return false;
		}
	}

	/**
	 * 判断字符串是否是符合datetime日期格式.
	 * 
	 * @param strDate
	 *            具有日期格式的字符串(yyyy-MM-dd HH:mm:ss)
	 * 
	 * @return boolean 是否是日期格式
	 */
	public static boolean isDatetime(String strDate) {
		try {
			SimpleDateFormat sdfDatetime = new SimpleDateFormat(DATETIME_FORMAT);
			sdfDatetime.parse(strDate);
			return true;
		} catch (ParseException pe) {
			return false;
		}
	}

	/**
	 * 把数据库时间转换为java时间.
	 * 
	 * @param date
	 *            数据库时间对象
	 * @return Date 返回日期类型
	 */
	public static Date toDate(java.sql.Date date) {
		return date == null ? null : new java.util.Date(date.getTime());
	}

	/**
	 * 把数据库时间转换为java时间.
	 * 
	 * @param date
	 *            数据库时间对象
	 * @return Date 返回日期类型
	 */
	public static Date toDate(java.sql.Timestamp date) {
		return date == null ? null : new java.util.Date(date.getTime());
	}

	/**
	 * 把字符串转换为日期类型.
	 * 
	 * @param strDate
	 *            具有日期格式的字符串(yyyy-MM-dd)
	 * 
	 * @return Date 返回日期类型
	 */
	public static Date toDate(String strDate) {
		try {
			SimpleDateFormat sdfDate = new SimpleDateFormat(DATE_FORMAT);
			return sdfDate.parse(strDate);
		} catch (ParseException pe) {
			return null;
		}
	}

	/**
	 * 把字符串转换为日期时间类型.
	 * 
	 * @param strDate
	 *            具有日期格式的字符串
	 * @param strFormat
	 *            日期格式(yyyy-MM-dd HH:mm:ss)
	 * 
	 * @return Date 返回日期时间类型
	 */
	public static Date toDate(String strDate, String strFormat) {
		try {
			SimpleDateFormat df = new SimpleDateFormat(strFormat);
			return df.parse(strDate);
		} catch (ParseException pe) {
			return null;
		}
	}

	/**
	 * 把字符串转换为日期时间类型.
	 * 
	 * @param strDate
	 *            具有日期格式的字符串(yyyy-MM-dd HH:mm:ss)
	 * 
	 * @return Date 返回日期时间类型
	 */
	public static Date toDatetime(String strDate) {
		try {
			SimpleDateFormat sdfDatetime = new SimpleDateFormat(DATETIME_FORMAT);
			return sdfDatetime.parse(strDate);
		} catch (ParseException pe) {
			return null;
		}
	}

	/**
	 * 把字符串转换为日期时间类型.
	 * 
	 * @param strDate
	 *            具有日期格式的字符串
	 * @param strFormat
	 *            日期格式(yyyy-MM-dd HH:mm:ss)
	 * 
	 * @return Date 返回日期时间类型
	 */
	public static Date toDatetime(String strDate, String strFormat) {
		return toDate(strDate, strFormat);
	}

	/**
	 * 把日期变量转换为字符串.
	 * 
	 * @param dtDate
	 *            要转换的日期变量
	 * 
	 * @return String 日期转换后的字符串(yyyy-MM-dd)
	 */
	public static String dateToString(Date dtDate) {
		SimpleDateFormat sdfDate = new SimpleDateFormat(DATE_FORMAT);
		return sdfDate.format(dtDate);
	}

	/**
	 * 把日期变量按指定的格式转换为字符串.
	 * 
	 * @param dtDate
	 *            要转换的日期变量
	 * @param strFormat
	 *            格式yyyy-MM-dd HH:mm:ss
	 * 
	 * @return 日期转换后的字符串
	 */
	public static String dateToString(Date dtDate, String strFormat) {
		SimpleDateFormat df = new SimpleDateFormat(strFormat);
		return df.format(dtDate);
	}

	/**
	 * 把日期变量按datetime型（yyyy-MM-dd HH:mm:ss）转换为字符串.
	 * 
	 * @param dtDate
	 *            要转换的日期变量 return 日期转换后的字符串
	 * 
	 * @return the string
	 */
	public static String datetimeToString(Date dtDate) {
		SimpleDateFormat sdfDatetime = new SimpleDateFormat(DATETIME_FORMAT);
		return sdfDatetime.format(dtDate);
	}

	/**
	 * 转换日期字符串成 年(四位)-月(两位)-天(两位) 小时:分钟:秒 (用在SQL中).
	 * 
	 * @param strDate
	 *            要转换的日期字符串
	 * 
	 * @return 转换后的日期字符串
	 */
	public static String transDate(String strDate) {
		return "to_date('" + strDate + "','yyyy-mm-dd')";
	}

	/**
	 * 转换日期成指定的格式 (用在SQL).
	 * 
	 * @param strDate
	 *            要转换的日期字符串
	 * @param strFormat
	 *            格式 (yyyy-mm-dd hh24:mi:ss)
	 * 
	 * @return String 转换后的日期字符串
	 */
	public static String transDate(String strDate, String strFormat) {
		return "to_date('" + strDate + "','" + strFormat + "')";
	}

	/**
	 * 转换日期成指定的Datatime型格式 (用在SQL插入,修改中).
	 * 
	 * @param strDate
	 *            要转换的日期字符串 (yyyy-mm-dd hh24:mi:ss)
	 * 
	 * @return String 转换后的日期字符串
	 */
	public static String transDatetime(String strDate) {
		return "to_date('" + strDate + "','yyyy-mm-dd hh24:mi:ss')";
	}

	/**
	 * 按 年(四位)-月(两位)-天(两位) 显示日期 (用在SQL中).
	 * 
	 * @param strDate
	 *            要显示的日期字符串
	 * 
	 * @return String 转换后的日期字符串
	 */
	public static String showDate(String strDate) {
		return "to_char(" + strDate + ",'yyyy-mm-dd')";
	}

	/**
	 * 按指定格式显示日期 (用在SQL中).
	 * 
	 * @param strDate
	 *            要显示的日期字符串
	 * @param strFormat
	 *            格式
	 * 
	 * @return String 转换后的日期字符串
	 */
	public static String showDate(String strDate, String strFormat) {
		return "to_char(" + strDate + ",'" + strFormat + "')";
	}

	/**
	 * 按指定格式显示日期 (用在SQL中).
	 * 
	 * @param strDate
	 *            要显示的日期字符串 yyyy-mm-dd hh24:mi:ss
	 * 
	 * @return String 转换后的日期字符串
	 */
	public static String showDatetime(String strDate) {
		return "to_char(" + strDate + ",'yyyy-mm-dd hh24:mi:ss')";
	}

	/**
	 * 根据生日算年龄.
	 * 
	 * @param birthDay
	 *            出生日期
	 * 
	 * @return String oracle计算年龄函数
	 */
	public static String yearOLD(String birthDay) {
		return "floor(months_between(SYSDATE," + birthDay + ")/12)";
	}

	/**
	 * 把具有日期格式("yyyy-MM-dd")的字符串转换为SQL日期类型.
	 * 
	 * @param strDate
	 *            具有日期格式的字符串
	 * 
	 * @return java.sql.Date 返回SQL日期类型
	 * 
	 * @throws BaseException
	 *             the exception
	 */
	public static java.sql.Date toSqlDate(String strDate) throws BaseException {
		return dateToSqlDate(toDate(strDate));
	}

	/**
	 * 把具有日期格式（format 格式）的字符串转换为日期类型.
	 * 
	 * @param strDate
	 *            具有日期格式的字符串
	 * @param strFormat
	 *            指定的日期格式
	 * 
	 * @return Date 返回日期类型
	 * 
	 * @throws BaseException
	 *             the exception
	 */
	public static java.sql.Date toSqlDate(String strDate, String strFormat) throws BaseException {
		return dateToSqlDate(toDate(strDate, strFormat));
	}

	/**
	 * 将java日期转换为sql日期.
	 * 
	 * @param date
	 *            需要转换的日期
	 * 
	 * @return java.sql.Date 转换后的日期
	 */
	public static java.sql.Date dateToSqlDate(java.util.Date date) {
		return new java.sql.Date(date.getTime());
	}

	/**
	 * 将java日期转换为sql时间戳.
	 * 
	 * @param date
	 *            需要转换的日期
	 * 
	 * @return java.sql.Timestamp 转换后的时间戳
	 */
	public static java.sql.Timestamp dateToTimestamp(java.util.Date date) {
		return new java.sql.Timestamp(date.getTime());
	}

	/**
	 * 将字符串转换为时间戳.
	 * 
	 * @param strDate
	 *            需要转换的字符串 格式缺省为"yyyy-MM-dd HH:mm:ss"
	 * 
	 * @return java.sql.Timestamp 转换后的时间戳
	 * 
	 * @throws BaseException
	 *             the exception
	 */
	public static java.sql.Timestamp toTimestamp(String strDate) throws BaseException {
		if (strDate.indexOf("/") > 0) {
			return dateToTimestamp(toDatetime(strDate, "yyyy/MM/dd HH:mm:ss"));
		} else {
			return dateToTimestamp(toDatetime(strDate));
		}
	}

	/**
	 * 将指定格式的字符串转换为时间戳.
	 * 
	 * @param strDate
	 *            需要转换的字符串 格式缺省为"yyyy-MM-dd HH:mm:ss"
	 * @param format
	 *            时间格式
	 * 
	 * @return java.sql.Timestamp 转换后的时间戳
	 * 
	 * @throws BaseException
	 *             the exception
	 */
	public static java.sql.Timestamp toTimestamp(String strDate, String format) throws BaseException {
		return dateToTimestamp(toDatetime(strDate, format));
	}

	/**
	 * 求日期的年份.
	 * 
	 * @param dtDate
	 *            日期变量
	 * 
	 * @return 年份
	 */
	public static int getYear(Date dtDate) {
		try {
			Calendar calAt = new GregorianCalendar();
			calAt.setTime(dtDate);
			return calAt.get(Calendar.YEAR);
		} catch (Exception pe) {
			return 0;
		}
	}

	/**
	 * 求日期的月份.
	 * 
	 * @param dtDate
	 *            日期变量
	 * 
	 * @return 月份
	 */

	public static int getMonth(Date dtDate) {
		try {
			Calendar calAt = new GregorianCalendar();
			calAt.setTime(dtDate);
			return calAt.get(Calendar.MONTH) + 1;
		} catch (Exception pe) {
			return 0;
		}

	}

	/**
	 * 求日期的月份.
	 * 
	 * @param dtDate
	 *            日期变量
	 * 
	 * @return 月份
	 */

	public static int getDateOfMonth(Date dtDate) {
		try {
			Calendar calAt = new GregorianCalendar();
			calAt.setTime(dtDate);
			return calAt.get(Calendar.DATE);
		} catch (Exception pe) {
			return 0;
		}

	}

	/**
	 * 求当前日期下一个月的年月.
	 * 
	 * @param year
	 *            年
	 * @param month
	 *            月
	 * @param day
	 *            日
	 * 
	 * @return string
	 */

	public static String getYearMonth(int year, int month, int day) {
		try {
			int iYear = 0;
			int iMonth = 0;
			String strYearMonth;
			Calendar calAt = new GregorianCalendar(year, month, day);
			iYear = calAt.get(Calendar.YEAR);
			iMonth = calAt.get(Calendar.MONTH) + 1;
			String strMonth = "";
			if (Integer.toString(iMonth).length() == 1) {
				strMonth = "0" + Integer.toString(iMonth);
			} else {
				strMonth = Integer.toString(iMonth);
			}
			strYearMonth = Integer.toString(iYear) + strMonth;
			return strYearMonth;
		} catch (Exception pe) {
			return "0";
		}
	}

	/**
	 * 求日期所在月份的第一天.
	 * 
	 * @param date
	 *            时间对象
	 * 
	 * @return 日期对象
	 */
	public static Date getFirstDateOfMonth(Date date) {
		try {
			Calendar cal = new GregorianCalendar();
			cal.setTime(getDate(date));

			cal.set(Calendar.DATE, 1);
			return cal.getTime();
		} catch (Exception pe) {
			return null;
		}
	}

	/**
	 * 求日期所在月份的最后一天.
	 * 
	 * @param date
	 *            时间对象
	 * 
	 * @return 日期对象
	 */
	public static Date getLastDateOfMonth(Date date) {
		try {
			Calendar cal = new GregorianCalendar();
			cal.setTime(getDate(date));

			cal.set(Calendar.DATE, 1);
			cal.add(Calendar.MONTH, 1);
			cal.add(Calendar.DATE, -1);
			return cal.getTime();
		} catch (Exception pe) {
			return null;
		}
	}

	/**
	 * 将指定的（有符号的）时间量添加到给定的日期对象中.
	 * 
	 * @param date
	 *            日期对象
	 * @param field
	 *            日历字段（见java.util.Calendar)
	 * @param amount
	 *            为字段添加的日期或时间量
	 * 
	 * @return 处理以后的日期对象
	 */
	public static Date add(Date date, int field, int amount) {
		try {
			Calendar cal = new GregorianCalendar();
			cal.setTime(date);

			cal.add(field, amount);

			return cal.getTime();
		} catch (Exception pe) {
			return null;
		}
	}

	/**
	 * 增加指定的秒数.
	 * 
	 * @param date
	 *            日期对象
	 * @param amount
	 *            为字段添加的秒数
	 * 
	 * @return 处理以后的日期对象
	 */
	public static Date addSeconds(Date date, int amount) {
		return add(date, Calendar.SECOND, amount);
	}

	/**
	 * 增加指定的分钟数.
	 * 
	 * @param date
	 *            日期对象
	 * @param amount
	 *            为字段添加的分钟数
	 * 
	 * @return 处理以后的日期对象
	 */
	public static Date addMinutes(Date date, int amount) {
		return add(date, Calendar.MINUTE, amount);
	}

	/**
	 * 增加指定的小时数.
	 * 
	 * @param date
	 *            日期对象
	 * @param amount
	 *            为字段添加的小时数
	 * 
	 * @return 处理以后的日期对象
	 */
	public static Date addHours(Date date, int amount) {
		return add(date, Calendar.HOUR, amount);
	}

	/**
	 * 增加指定的日数.
	 * 
	 * @param date
	 *            日期对象
	 * @param amount
	 *            为字段添加的日数
	 * 
	 * @return 处理以后的日期对象
	 */
	public static Date addDays(Date date, int amount) {
		return add(date, Calendar.DATE, amount);
	}

	/**
	 * 增加指定的月数.
	 * 
	 * @param date
	 *            日期对象
	 * @param amount
	 *            为字段添加的月数
	 * 
	 * @return 处理以后的日期对象
	 */
	public static Date addMonths(Date date, int amount) {
		return add(date, Calendar.MONTH, amount);
	}

	/**
	 * 增加指定的月数.
	 * 
	 * @param strDate
	 *            日期字符串(yyyyMM,yyyyMMdd,yyyy-MM,yyyy-MM-dd)
	 * @param amount
	 *            为字段添加的月数
	 * 
	 * @return 处理以后的日期字符串
	 * 
	 * @throws BaseException
	 *             the exception
	 */
	public static String addMonths(String strDate, int amount) throws BaseException {
		if (!StringUtils.hasText(strDate)) {
			return "";
		}

		String strInput = strDate.trim();
		String strReturn = "";
		int len = strInput.length();
		switch (len) {
		case 6:
			strReturn = dateToString(addMonths(toDate(strInput + "01", "yyyyMMdd"), amount), "yyyyMM");
			break;
		case 7:
			strReturn = dateToString(addMonths(toDate(strInput + "-01"), amount), "yyyy-MM");
			break;
		case 8:
			strReturn = dateToString(addMonths(toDate(strInput, "yyyyMMdd"), amount), "yyyyMMdd");
			break;
		case 10:
			strReturn = dateToString(addMonths(toDate(strInput), amount));
			break;
		default:
			throw new BaseException("不支持的日期格式(" + strDate + ")");
		}

		return strReturn;
	}

	/**
	 * 求日期部分.
	 * 
	 * @param date
	 *            时间对象
	 * 
	 * @return 日期对象
	 */
	public static Date getDate(Date date) {
		try {
			return toDate(dateToString(date));
		} catch (Exception pe) {
			return null;
		}
	}

	/**
	 * 求日期时间部分.
	 * 
	 * @param year
	 *            年
	 * @param month
	 *            月
	 * @param dayOfMonth
	 *            天数
	 * @param hourOfDay
	 *            小时
	 * @param minute
	 *            分钟
	 * @param second
	 *            秒
	 * 
	 * @return 日期对象
	 */
	public static Date getDate(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second) {
		Calendar c = new GregorianCalendar(year, month - 1, dayOfMonth, hourOfDay, minute, second);
		return c.getTime();
	}

	/**
	 * 求日期部分.
	 * 
	 * @param year
	 *            年
	 * @param month
	 *            月
	 * @param dayOfMonth
	 *            天数
	 * 
	 * @return 日期对象
	 */
	public static Date getDate(int year, int month, int dayOfMonth) {
		Calendar c = new GregorianCalendar(year, month - 1, dayOfMonth, 0, 0, 0);
		return c.getTime();
	}

	/**
	 * 求日期部分.
	 * 
	 * @param month
	 *            月
	 * @param dayOfMonth
	 *            天数
	 * 
	 * @return 日期对象
	 */
	public static Date getDate(int month, int dayOfMonth) {
		Calendar c = new GregorianCalendar();

		c.set(Calendar.MONTH, month - 1);
		c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);

		return c.getTime();
	}

	/**
	 * 求日期部分.
	 * 
	 * @param dayOfMonth
	 *            天数
	 * 
	 * @return 日期对象
	 */
	public static Date getDate(int dayOfMonth) {
		Calendar c = new GregorianCalendar();

		c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);

		return c.getTime();
	}

	/**
	 * 求日期部分.
	 * 
	 * @return 日期对象
	 */
	public static Date getDate() {
		Calendar c = new GregorianCalendar();

		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);

		return c.getTime();
	}

	/**
	 * 解析日期字符串(忽略时间).
	 * 
	 * @param strDate
	 *            字符串(yyyy-MM,yyy-MM-dd,yyyyMM,yyyyMMdd)
	 * 
	 * @return 日期对象
	 * 
	 * @throws BaseException
	 *             the exception
	 */
	public static Date parseDate(String strDate) throws BaseException {
		if (!StringUtils.hasText(strDate)) {
			return null;
		}

		String strInput = strDate.trim();
		Date dateReturn = null;

		int len = strInput.length();
		if (len > 10) {
			strInput = strInput.substring(0, 10);
		}
		switch (len) {
		case 6:
			dateReturn = getDate(Integer.parseInt(strInput.substring(0, 4)), Integer.parseInt(strInput.substring(4, 6)), 1);
			break;
		case 7:
			dateReturn = getDate(Integer.parseInt(strInput.substring(0, 4)), Integer.parseInt(strInput.substring(5, 7)), 1);
			break;
		case 8:
			dateReturn = getDate(Integer.parseInt(strInput.substring(0, 4)), Integer.parseInt(strInput.substring(4, 6)), Integer.parseInt(strInput.substring(6, 8)));
			break;
		case 10:
			dateReturn = getDate(Integer.parseInt(strInput.substring(0, 4)), Integer.parseInt(strInput.substring(5, 7)), Integer.parseInt(strInput.substring(8, 10)));
			break;
		default:
			throw new BaseException("不支持的日期格式(" + strDate + ")");
		}

		return dateReturn;
	}

	/**
	 * 求两个日期字符串相差的天数(日期2-日期1).
	 * 
	 * @param date1
	 *            日期1
	 * @param date2
	 *            日期2
	 * 
	 * @return String 两者相差日期(不考虑小时的差)
	 * 
	 * @throws BaseException
	 *             the exception
	 */
	public static long afterDays(String date1, String date2) throws BaseException {
		return afterDays(parseDate(date1), parseDate(date2));
	}

	/**
	 * 求两个日期对象相差的天数(日期2-日期1).
	 * 
	 * @param date1
	 *            日期对象1
	 * @param date2
	 *            日期对象2
	 * 
	 * @return String 两者相差日期(不考虑小时的差)
	 * 
	 * @throws BaseException
	 *             the exception
	 */
	public static long afterDays(Date date1, Date date2) throws BaseException {
		try {
			String strDate1_temp = dateToString(date1);
			Date dtDate1_temp = toDate(strDate1_temp);
			String strDate2_temp = dateToString(date2);
			Date dtDate2_temp = toDate(strDate2_temp);
			long days = (dtDate2_temp.getTime() - dtDate1_temp.getTime()) / (1000 * 60 * 60 * 24);
			return days;
		} catch (Exception ex) {
			throw new BaseException("计算天数差出错", ex);
		}
	}

	/**
	 * 求两个日期字符串的月数差(日期2-日期1).
	 * 
	 * @param date1
	 *            日期字符串1
	 * @param date2
	 *            日期字符串2
	 * 
	 * @return 月数
	 * 
	 * @throws BaseException
	 *             the exception
	 */
	public static long afterMonths(String date1, String date2) throws BaseException {
		return afterMonths(parseDate(date1), parseDate(date2));
	}

	/**
	 * 求两个日期对象的月数差(日期2-日期1).
	 * 
	 * @param date1
	 *            日期对象1
	 * @param date2
	 *            日期对象2
	 * @return 月数
	 * @throws BaseException
	 *             the exception
	 */
	public static long afterMonths(Date date1, Date date2) throws BaseException {
		try {
			Calendar c1 = new GregorianCalendar();
			c1.setTime(date1);
			Calendar c2 = new GregorianCalendar();
			c2.setTime(date2);
			return (c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR)) * 12 + (c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH));
		} catch (Exception ex) {
			throw new BaseException("计算月份差出错", ex);
		}
	}

	/**
	 * 求上月的最后一天.
	 * 
	 * @param dtDate
	 *            日期对象
	 * @return Date
	 */
	public static Date getLastDayOfLastMonth(Date dtDate) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(dtDate);

		calendar.set(Calendar.DATE, 1); // 设为当前月的1号
		calendar.add(Calendar.DATE, -1); // 减一天，变为上月最后一天

		calendar.set(Calendar.HOUR, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTime();
	}

	/**
	 * 转换日期对象为GMT字符串.
	 * 
	 * @param date
	 *            日期对象
	 * @return GMT字符串
	 */
	public static String toGMTString(final Date date) {
		final SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
		df.setTimeZone(TimeZone.getTimeZone("GMT")); // modify Time Zone.
		return df.format(date);
	}

	public static boolean isWeekDay(final Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 获得本天的开始时间，即2012-01-01 00:00:00
	 * 
	 * @return
	 */
	public static Date getCurrentDayStartTime(Date now) {
		try {
			SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
			now = shortSdf.parse(shortSdf.format(now));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return now;
	}

	/**
	 * 获得本天的结束时间，即2012-01-01 23:59:59
	 * 
	 * @return
	 */
	public  static Date getCurrentDayEndTime(Date now) {
		try {
			SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
			now = longSdf.parse(shortSdf.format(now) + " 23:59:59");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return now;
	}
	

	public static String getCurrentYear() {
		Date date = new Date();
		return dateToString(date, "yyyy");
	}

}
